package cn.sdfykjyxgs.synserver.controller;

import cn.sdfykjyxgs.syncommon.entity.FileChangeLog;
import cn.sdfykjyxgs.syncommon.service.FileChangeLogService;
import cn.sdfykjyxgs.synserver.util.JnotifyListening;
import cn.sdfykjyxgs.synserver.util.SpeedLimiter;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Arrays;
import java.util.List;

@Controller
@ResponseBody
public class FileChangeLogController {
    @Resource
    FileChangeLogService fileChangeLogService;

    /**
     * 服务是否在线
     *
     * @return
     */
    @GetMapping("/isOnline")
    public Object isOnline() {
        return true;
    }

    @GetMapping("/queryAll")
    public Object queryAll() {
        List<FileChangeLog> list = fileChangeLogService.list();
        return list;
    }

    @GetMapping("/insert")
    public Object insert() {
//        FileChangeLog entity = new FileChangeLog();
//        entity.setName(UUID.randomUUID().toString());
//        entity.setTime(new Date());
//        entity.setUrl("insert");
//        entity.setUrl("file/test");
//        entity.setType(0);
//        entity.setSynStatus(false);
//        fileChangeLogService.save(entity);
        return "success";
    }

    @GetMapping("/syncData")
    public Page<FileChangeLog> syncData() {
        Page<FileChangeLog> fileChangeLogPage = fileChangeLogService.syncData();
        return fileChangeLogPage;
    }

    @GetMapping("/queryById")
    public FileChangeLog queryById(@RequestParam(value = "fileId") Long fileId) {
        FileChangeLog fileChangeLog = fileChangeLogService.queryById(fileId);
        return fileChangeLog;
    }

    @GetMapping("/refreshStatus")
    public Boolean refreshStatus(@RequestParam(value = "fileId") Long fileId) {
        fileChangeLogService.refreshStatus(fileId);
        return true;
    }

    @GetMapping("/limitSpeed")
    public void limitSpeed(@RequestParam(value = "speed", defaultValue = "300") int speed, @RequestParam(value = "fileId") Long fileId, HttpServletResponse response) throws IOException {
        FileChangeLog byId = fileChangeLogService.getById(fileId);
        //找打此文件最新的一条日志记录并且获取文件当前存在的物理目录
        QueryWrapper<FileChangeLog> fileChangeLogQueryWrapper = new QueryWrapper<>();
        if (byId == null) {
            // 设置状态码
            responseNone(response);
        }
        fileChangeLogQueryWrapper = new QueryWrapper<>();
        fileChangeLogQueryWrapper.lambda()
                .eq(FileChangeLog::getKey, byId.getKey())
                .orderByDesc(FileChangeLog::getId).last("limit 1");
        byId = fileChangeLogService.getOne(fileChangeLogQueryWrapper);
        File path = new File(byId.getUrl() + "\\" + byId.getName());

        String keyHierarchy = byId.getKeyHierarchy();
        fileChangeLogQueryWrapper = new QueryWrapper<>();
        fileChangeLogQueryWrapper.lambda()
                .eq(FileChangeLog::getKey, keyHierarchy)
                .orderByDesc(FileChangeLog::getId).last("limit 1");
        FileChangeLog old = fileChangeLogService.getOne(fileChangeLogQueryWrapper);
        if (byId.getKey().equals(keyHierarchy)) old = null;//处理自身为 keyHierarchy
        if (old != null) {
            String name = old.getName();
            String substring = byId.getName().substring(byId.getName().lastIndexOf("\\"));
            String s = name + substring;
            path = new File(byId.getUrl() + "\\" + s);
            if (!path.exists()) responseNone(response);
        }
        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment;filename=" + path.getName());
        response.setHeader("Content-Length", "" + path.length());
        response.setContentLengthLong(path.length());
        InputStream inputStream = new FileInputStream(path);
        OutputStream outputStream = response.getOutputStream();
        try {
            byte[] buffer = new byte[1024];
            int length;
            SpeedLimiter speedLimiter = new SpeedLimiter(SpeedLimiter.maxRate);
            while ((length = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, length);
                speedLimiter.delayNextBytes(length);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            inputStream.close();
            outputStream.close();
        }

    }

    @GetMapping("/changeSpeed")
    public Boolean changeSpeed(@RequestParam(value = "maxRate") Integer maxRate, @RequestParam(value = "filterFormat") String filterFormat) {
        if (maxRate != null) {
            SpeedLimiter.maxRate = maxRate;
        }
        if (!StringUtils.isEmpty(filterFormat)) {
            JnotifyListening.filterFormats = (Arrays.asList(filterFormat.split(",")));
        }
        return true;
    }

    public void responseNone(HttpServletResponse response) throws IOException {
        // 设置状态码
        response.setStatus(HttpServletResponse.SC_OK);

        // 设置响应的内容类型
        response.setContentType("text/plain");
        response.setCharacterEncoding("UTF-8");
        // 向响应中写入内容
        response.getWriter().write("暂无文件");
        return;
    }
}
